package logic.common.team;

import java.util.ArrayList;
import java.util.List;

import com.jme.math.Vector3f;

import logic.common.team.processes.FrigateProcess;
import logic.common.team.processes.ProcessAddEvent;
import logic.common.team.processes.ProcessFinishEvent;
import logic.common.team.processes.ProcessStartEvent;
import logic.common.team.processes.TeamProcessListener;
import logic.nodes.TeamNode;
import logic.ships.frigate.Frigate;

public class FrigateAction extends TeamAction {
	
	private int pendingFrigates;
	
	public FrigateAction(Team team) {
		super(team);
		
		team.addTeamProcessListener(new TeamProcessListener() {
			@Override
			public void processFinished(ProcessFinishEvent event) {
				if(event.getTeamProcess() instanceof FrigateProcess) pendingFrigates--;
			}
			
			@Override
			public void processStarted(ProcessStartEvent event) {}
			@Override
			public void processAdded(ProcessAddEvent event) {}
		});
	}
	
	@Override
	public void performAction() {
		if(newFrigateNecessary()) {
			team.spendTeamMoney(team.getNewFrigateProperties().getCosts());
			team.addTeamProcess(new FrigateProcess(team));
			pendingFrigates++;
		}
		
		for(Frigate frigate : team.getFrigates()) {
			if(frigate.getCurrentTarget() == null || frigate.getCurrentTarget().isDestroyed()) {
				TeamNode newTarget = getBestTarget(frigate);
				frigate.setTarget(newTarget);
				team.getOpenFrigateTargets().remove(newTarget);
			}
		}
	}
	
	private TeamNode getBestTarget(Frigate frigate) {
		Vector3f frigateLoc = frigate.getLocalTranslation();
		
		TeamNode target = team.getEnemyTeam().getMotherShip();
		float minDist = frigateLoc.distance(target.getLocalTranslation());
		
		List<TeamNode> targets = new ArrayList<TeamNode>(team.getOpenFrigateTargets());
		
		for(TeamNode node : targets) {
			float dist = node.getLocalTranslation().distance(frigateLoc);
			if(dist < minDist) {
				minDist = dist;
				target = node;
			}
		}
		
		return target;
	}
	
	private boolean newFrigateNecessary() {
		if(team.getTeamMoney() < team.getNewFrigateProperties().getCosts()) return false;
		
		return team.getFrigates().size() + pendingFrigates < Team.MAX_FRIGATES;
	}
}